﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Geolocation;

namespace YellowMap
{
    public class GooglePlaceRequest
    {
        static GooglePlaceRequest()
        {
            ApiKey = "AIzaSyAo3PYOTkQVXbn_Xz-v0OMuDH89YAhjSd8";
        }

        /// <summary>
        /// DataType, latitude, longtidue, radius, types, name, keywords, apikey, rankby
        /// </summary>
        const string baseURL = "https://maps.googleapis.com/maps/api/place/search/{0}?location={1},{2}&radius={3}&types={4}&name={5}&keyword={6}&sensor=true&rankby={8}&key={7}&pagetoken={9}";
        
        List<string> _types = new List<string>();
        List<string> _keywords = new List<string>();

        /// <summary>
        /// Your application's API key. This key identifies your application for purposes of quota management and so that Places added from your application are made immediately available to your app.
        /// </summary>
        public static string ApiKey { get; set; }

        /// <summary>
        /// The respond data is json or xml
        /// </summary>
        private DataType DataType { get; set; }

        /// <summary>
        /// A term to be matched against the names of Places.
        /// </summary>
        public string LocationName { get; set; }

        /// <summary>
        /// The latitude around which to retrieve Place information.
        /// </summary>
        public double Lattitude { get; set; }

        /// <summary>
        /// The longitude around which to retrieve Place information.
        /// </summary>
        public double Longtitude { get; set; }

        /// <summary>
        /// Defines the distance (in meters) within which to return Place results. The maximum allowed radius is 50 000 meters
        /// </summary>
        public int Radius { get; set; }

        /// <summary>
        /// Request command
        /// </summary>
        public string Command { get; set; }

        public string PageToken { get; set; }


        /// <summary>
        /// Specifies the order in which results are listed. Possible values are: prominence (default), distance
        /// </summary>
        public RankByEnum Rankby { get; set; }

        /// <summary>
        /// Clone object
        /// </summary>
        public GooglePlaceRequest Clone
        {
            get
            {
                return MemberwiseClone() as GooglePlaceRequest;
            }
        }


        public GooglePlaceRequest()
        {
            Command = "";
            DataType = DataType.json;
            LocationName = "";
            Lattitude = 10.823105;
            Longtitude = 106.629682;
            Radius = 2500;
            Rankby = RankByEnum.prominence;
            PageToken = "";
        }

        /// <summary>
        /// A term to be matched against all content that Google has indexed for this Place, including but not limited to name, type, and address, as well as customer reviews and other third-party content.
        /// </summary>
        /// <param name="keywords">List keyword</param>
        public void AddKeyWords(params string[] keywords)
        {
            _keywords.AddRange(keywords);
        }

        /// <summary>
        /// Restricts the results to Places matching at least one of the specified types. Types should be separated with a pipe symbol
        /// </summary>
        /// <param name="types"> List type</param>
        public void AddTypes(params string[] types)
        {
            _types.AddRange(types);
        }

       

        public override string ToString()
        {
            string types = __types();
            string keyword = __keywords();
            int r = -1;
            if (Rankby == RankByEnum.prominence)
            {
                r = Radius;
            }
            Lattitude = Math.Round(Lattitude,8);
            Longtitude = Math.Round(Longtitude, 8);
            string baseUrl = string.Format(GooglePlaceRequest.baseURL,
                    DataType.ToString().ToLower(),
                    Lattitude.ToString().Replace(",","."),
                    Longtitude.ToString().Replace(",", "."),
                    r,
                    types,
                    "\"" + LocationName + "\"",
                    keyword,
                    ApiKey,
                    Rankby.ToString().ToLower(),
                    PageToken
                );

            if (PageToken == "")
            {
                baseUrl = baseUrl.Replace("&pagetoken=", "");
            }

            if (r == -1)
            {
                baseUrl = baseUrl.Replace("&radius=-1", "");
            }

            if (types == "")
            {
                baseUrl = baseUrl.Replace("&types=", "");
            }

            if (keyword == "")
            {
                baseUrl = baseUrl.Replace("&keyword=", "");
            }

            if (LocationName == "")
            {
                baseUrl = baseUrl.Replace("&name=", "");
            }



            baseUrl = baseUrl.Replace("|", "%7C");
            baseUrl = baseUrl.Replace(" ", "%20");
            baseUrl = baseUrl.Replace("\"\"", "");
            return baseUrl;
        }

        string __types()
        {
            string output = "";
            foreach (var item in _types)
            {
                output += item + "|";
            }
            output = output.Trim(new char[]{'|'});
            return output;
        }

        string __keywords()
        {
            string output = "";
            foreach (var item in _keywords)
            {
                output += item + "+";
            }
            output = output.Trim(new char[] { '+' });
            return output;
        }

    }

    public enum RankByEnum
    {
        /// <summary>
        /// This option sorts results based on their importance. Ranking will favor prominent places within the specified area. Prominence can be affected by a Place's ranking in Google's index, the number of check-ins from your application, global popularity, and other factors.
        /// </summary>
        prominence, 
        /// <summary>
        /// This option sorts results in ascending order by their distance from the specified location. Ranking results by distance will set a fixed search radius of 50km. One or more of keyword, name, or types is required.
        /// </summary>
        distance
    }

    public enum DataType
    {
        json, xml
    }
}
